package com.elitel.frame.main.config.serviceaccess.interceptor;

import com.elitel.common.utils.IpUtils;
import com.elitel.frame.base.service.SysPrjServiceService;
import com.elitel.frame.core.util.ApplicationContextHelper;
import com.elitel.frame.main.config.serviceaccess.util.ServiceAccessPrintWriterUtil;
import com.elitel.frame.main.config.serviceaccess.util.ServiceAccessResponseStatus;
import com.elitel.frame.main.config.serviceaccess.util.ServiceAccessTimeLimit;
import com.elitel.frame.main.dao.AcAppMapper;
import com.elitel.frame.main.dao.AcAppServiceMapper;
import com.elitel.frame.main.entity.AcApp;
import com.elitel.frame.main.entity.AcAppService;
import com.elitel.frame.main.entity.SysPrjservice;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import static com.elitel.common.core.constant.RequestConstant.*;

/**
 * 服务授权码限制拦截器
 * 1.验证AppCode 是否授权
 * 2.验证AppCode 授权的访问次数是否超限
 * 2.验证AppCode 授权的访问开始和结束日期
 * 2.验证AppCode 授权的访问开始和结束小时
 * 3.验证AppCode 授权的访问IP地址
 *
 * @author hi_bj
 * @since 2023-10-26
 */

public class AppCodeInterceptor implements HandlerInterceptor {

    /**
     * 时间格式范例
     */
    private String TimePattern = "yyyyMMddHHmmss";
    /**
     * 小时格式范例
     */
    private String HourPattern = "HHmmss";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        String serviceCode = request.getParameter(SERVICE_ID);
        String appCode = request.getParameter(APP_CODE);
        //获取服务基础信息
        SysPrjServiceService sysPrjServiceService = ApplicationContextHelper.getApplicationContext().getBean(SysPrjServiceService.class);
        SysPrjservice sysPrjservice = sysPrjServiceService.getSysPrjserviceByServiceCode(serviceCode);
        //获取访问控制-应用和服务关系
        AcAppServiceMapper acAppServiceMapper = ApplicationContextHelper.getApplicationContext().getBean(AcAppServiceMapper.class);
        List<AcAppService> appServiceList = acAppServiceMapper.getAllByServiceId(sysPrjservice.getGuid());
        //获取访问控制-应用基础信息
        AcAppMapper acAppMapper = ApplicationContextHelper.getApplicationContext().getBean(AcAppMapper.class);
        AcApp acApp = acAppMapper.selectByAppCode(appCode);
        //1.验证AppCode 是否授权
        AcAppService curAcAppService = null;
        for (AcAppService acAppService : appServiceList) {
            if (acAppService.getAppId().equals(acApp.getAppId())) {
                curAcAppService = acAppService;
                break;
            }
        }
        if (ObjectUtils.isEmpty(curAcAppService)) {
            ServiceAccessPrintWriterUtil.write(response, ServiceAccessResponseStatus.APP_CODE_NOT_AUTHORIZED.initValue());
            return false;
        }
        //验证IP地址
        String filterIp = acApp.getIp();
        if (!ObjectUtils.isEmpty(filterIp)) {
            //校验ip是否符合过滤串规则  过滤IP列表,多个IP‘;’分割，支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99`
            if (!IpUtils.isMatchedIp(filterIp, IpUtils.getIpAddr(request))) {
                ServiceAccessPrintWriterUtil.write(response, ServiceAccessResponseStatus.IPADDR_NOT_AUTHORIZED.initValue());
                return false;
            }
        }

        //2.验证AppCode 访问次数
        if (curAcAppService.getDailyCount() > 0 &&
                ServiceAccessTimeLimit.getAndSet(curAcAppService.getAppId(), appCode) > curAcAppService.getDailyCount()) {
            ServiceAccessPrintWriterUtil.write(response, ServiceAccessResponseStatus.APP_CODE_ACCESS_OVER_LIMIT.initValue());
            return false;
        }
        //3.验证访问开始和结束日期
        SimpleDateFormat sdfTime = new SimpleDateFormat(TimePattern);
        Date curDate = new Date();
        String curTime = sdfTime.format(curDate);
        if (!ObjectUtils.isEmpty(curAcAppService.getStartTime())) {
            String startTime = sdfTime.format(curAcAppService.getStartTime());
            if (Long.valueOf(curTime) < Long.valueOf(startTime)) {
                ServiceAccessPrintWriterUtil.write(response, ServiceAccessResponseStatus.APP_CODE_START_TIME_NOT_START.initValue());
                return false;
            }
        }
        if (!ObjectUtils.isEmpty(curAcAppService.getEndTime())) {
            String endTime = sdfTime.format(curAcAppService.getEndTime());
            if (Long.valueOf(curTime) > Long.valueOf(endTime)) {
                ServiceAccessPrintWriterUtil.write(response, ServiceAccessResponseStatus.APP_CODE_END_TIME_OVER_TIME.initValue());
                return false;
            }
        }
        //4.验证访问开始和结束小时
        SimpleDateFormat sdfHour = new SimpleDateFormat(HourPattern);
        String curHour = sdfHour.format(curDate);
        if (!ObjectUtils.isEmpty(curAcAppService.getStartHour())) {
            String startHour = curAcAppService.getStartHour().replaceAll(":", "");
            if (Long.valueOf(curHour) < Long.valueOf(startHour)) {
                ServiceAccessPrintWriterUtil.write(response, ServiceAccessResponseStatus.APP_CODE_START_HOUR_NOT_START.initValue());
                return false;
            }
        }
        if (!ObjectUtils.isEmpty(curAcAppService.getEndHour())) {
            String endHour = curAcAppService.getEndHour().replaceAll(":", "");
            if (Long.valueOf(curHour) > Long.valueOf(endHour)) {
                ServiceAccessPrintWriterUtil.write(response, ServiceAccessResponseStatus.APP_CODE_END_HOUR_OVER_TIME.initValue());
                return false;
            }
        }
        return true;
    }
}
